package com.chuangjiangx.member.coupon.ddd.domain.repository;

import com.chuangjiangx.commons.BeanUtils;
import com.chuangjiangx.commons.exception.BaseException;
import com.chuangjiangx.dddbase.Repository;
import com.chuangjiangx.dddbase.domain.shared.Timestamp;
import com.chuangjiangx.member.coupon.ddd.domain.model.*;
import com.chuangjiangx.member.coupon.dao.mapper.InMbrCouponMapper;
import com.chuangjiangx.member.coupon.dao.mapper.InMbrHasCouponMapper;
import com.chuangjiangx.member.coupon.dao.model.InMbrHasCoupon;
import com.chuangjiangx.member.coupon.dao.model.InMbrHasCouponExample;

import com.chuangjiangx.member.basic.ddd.domain.model.MemberId;
import com.chuangjiangx.member.basic.ddd.domain.model.StoreId;
import com.chuangjiangx.member.basic.ddd.domain.model.StoreUserId;
import com.chuangjiangx.member.coupon.ddd.domain.model.MbrHasCoupon;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.*;

@Component
public class MbrHasCouponRepository implements Repository<MbrHasCoupon, MbrHasCouponId> {

    private final InMbrHasCouponMapper inMbrHasCouponMapper;
    private final InMbrCouponMapper inMbrCouponMapper;

    @Autowired
    public MbrHasCouponRepository(InMbrHasCouponMapper inMbrHasCouponMapper,InMbrCouponMapper inMbrCouponMapper) {
        this.inMbrHasCouponMapper = inMbrHasCouponMapper;
        this.inMbrCouponMapper = inMbrCouponMapper;
    }


    @Override
    public MbrHasCoupon fromId(MbrHasCouponId id) {
        Objects.requireNonNull(id,"会员拥有卡券表id不能为空");
        InMbrHasCoupon inMbrHasCoupon = inMbrHasCouponMapper.selectByPrimaryKey(id.getId());
        return convertToEntity(inMbrHasCoupon);
    }

    @Override
    public void update(MbrHasCoupon entity) {
        Objects.requireNonNull(entity);
        InMbrHasCoupon in = convertToIn(entity);
        inMbrHasCouponMapper.updateByPrimaryKeySelective(in);
    }

    @Override
    public void save(MbrHasCoupon entity) {
        Objects.requireNonNull(entity);
        InMbrHasCoupon inMbrHasCoupon = convertToIn(entity);
        inMbrHasCouponMapper.insertSelective(inMbrHasCoupon);
        entity.setId(new MbrHasCouponId(inMbrHasCoupon.getId()));
    }

    /**
     * 获取会员拥有指定卡券列表
     */
    public List<InMbrHasCoupon> fromMbrCouponId(MemberId memberId, MbrCouponId mbrCouponId) {
        Objects.requireNonNull(memberId);
        Objects.requireNonNull(mbrCouponId);
        InMbrHasCouponExample example = new InMbrHasCouponExample();
        example.createCriteria().andMemberIdEqualTo(memberId.getId())
                .andMbrCouponIdEqualTo(mbrCouponId.getId());

        List<InMbrHasCoupon> inMbrHasCoupons = inMbrHasCouponMapper.selectByExample(example);
        if (inMbrHasCoupons == null || inMbrHasCoupons.size() == 0) {
            return new ArrayList<>();
        }
        return inMbrHasCoupons;
    }

    /**
     * 根据卡券核销码获取会员卡券信息
     */
    public MbrHasCoupon fromVerifyCode(String verifyCode) {
        Objects.requireNonNull(verifyCode);
        InMbrHasCouponExample example = new InMbrHasCouponExample();
        example.createCriteria().andVerifyCodeEqualTo(verifyCode);

        List<InMbrHasCoupon> inMbrHasCoupons = inMbrHasCouponMapper.selectByExample(example);
        if (inMbrHasCoupons == null || inMbrHasCoupons.size() == 0) {
            return null;
        }
        if (inMbrHasCoupons.size() > 1) {
            throw new BaseException("","数据异常，重复的核销码");
        }
        return convertToEntity(inMbrHasCoupons.get(0));
    }

    private MbrHasCoupon convertToEntity(InMbrHasCoupon in) {
        Objects.requireNonNull(in);
        MbrHasCoupon mbrHasCoupon = new MbrHasCoupon(
                new MemberId(in.getMemberId()),
                new MbrCouponId(in.getMbrCouponId()),
                VerifyStatus.getStatus(in.getVerifyStatus()),
                in.getClaimTime(),
                Optional.ofNullable(in.getVerifyStoreId()).map(StoreId::new).orElse(null),
                Optional.ofNullable(in.getVerifyStoreUserId()).map(StoreUserId::new).orElse(null),
                in.getVerifyTime(), VerifyTerminal.getTerminal(in.getVerifyTerminal()),in.getVerifyCode(),
                in.getUseTime(), WxVerifyStatus.getWxVerifyStatus(in.getWxVerifyStatus()), WxSyncStatus.getWxSyncStatus(in.getWxSyncStatus()));
        mbrHasCoupon.setId(new MbrHasCouponId(in.getId()));
        mbrHasCoupon.setTimestamp(new Timestamp(in.getCreateTime(),in.getUpdateTime()));
        return mbrHasCoupon;
    }

    private InMbrHasCoupon convertToIn(MbrHasCoupon mbrHasCoupon) {
        Objects.requireNonNull(mbrHasCoupon);
        InMbrHasCoupon in = new InMbrHasCoupon();
        BeanUtils.convertBean(mbrHasCoupon,in);
        in.setId(Optional.of(mbrHasCoupon).map(MbrHasCoupon::getId).map(MbrHasCouponId::getId).orElse(null));
        in.setCreateTime(mbrHasCoupon.getTimestamp().getCreateTime());
        in.setUpdateTime(mbrHasCoupon.getTimestamp().getUpdateTime());
        in.setUseTime(mbrHasCoupon.getUseTime());
        in.setMemberId(Optional.of(mbrHasCoupon).map(MbrHasCoupon::getMemberId).map(MemberId::getId).orElse(null));
        in.setMbrCouponId(Optional.of(mbrHasCoupon).map(MbrHasCoupon::getMbrCouponId).map(MbrCouponId::getId).orElse(null));
        in.setVerifyStatus(Optional.of(mbrHasCoupon).map(MbrHasCoupon::getVerifyStatus).map(status -> status.code).orElse(0));
        in.setVerifyStoreId(Optional.of(mbrHasCoupon).map(MbrHasCoupon::getVerifyStoreId).map(StoreId::getId).orElse(null));
        in.setVerifyStoreUserId(Optional.of(mbrHasCoupon).map(MbrHasCoupon::getVerifyStoreUserId).map(StoreUserId::getId).orElse(null));
        in.setVerifyTerminal(Optional.of(mbrHasCoupon).map(MbrHasCoupon::getVerifyTerminal).map(terminal -> terminal.code).orElse(1));
        in.setWxSyncStatus(Optional.of(mbrHasCoupon).map(MbrHasCoupon::getWxSyncStatus).map(wxSyncStatus -> wxSyncStatus.code).orElse(0));
        in.setWxVerifyStatus(Optional.of(mbrHasCoupon).map(MbrHasCoupon::getWxVerifyStatus).map(wxVerifyStatus -> wxVerifyStatus.code).orElse(0));
        return in;
    }

    public Long getCouponSizeByMemberId(Long memberId, Integer verifyStatus) {
        InMbrHasCouponExample example = new InMbrHasCouponExample();
        example.createCriteria().andVerifyStatusEqualTo(verifyStatus).andMemberIdEqualTo(memberId);
        return inMbrHasCouponMapper.countByExample(example);
    }
}
